package com.kensure.shike.zhang.service;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import co.kensure.exception.BusinessExceptionUtil;
import co.kensure.frame.JSBaseService;
import co.kensure.mem.CollectionUtils;
import co.kensure.mem.DateUtils;
import co.kensure.mem.MapUtils;
import co.kensure.mem.NumberUtils;

import com.kensure.basekey.BaseKeyService;
import com.kensure.shike.user.model.SKUser;
import com.kensure.shike.user.service.SKUserService;
import com.kensure.shike.zhang.dao.SkUserJinbiDao;
import com.kensure.shike.zhang.model.SKUserYue;
import com.kensure.shike.zhang.model.SKUserZhang;
import com.kensure.shike.zhang.model.SkUserJinbi;

/**
 * 试客金币流水服务实现类
 * 
 * @author fankd created on 2018-10-5
 * @since
 */
@Service
public class SkUserJinbiService extends JSBaseService {

	@Resource
	private SkUserJinbiDao dao;

	@Resource
	private BaseKeyService baseKeyService;

	@Resource
	private SKUserYueService sKUserYueService;

	@Resource
	private SKUserZhangService skUserZhangService;

	@Resource
	private SKUserService sKUserService;

	public SkUserJinbi selectOne(Long id) {
		return dao.selectOne(id);
	}

	public List<SkUserJinbi> selectByIds(Collection<Long> ids) {
		return dao.selectByIds(ids);
	}

	public List<SkUserJinbi> selectByWhere(Map<String, Object> parameters) {
		return dao.selectByWhere(parameters);
	}

	public long selectCountByWhere(Map<String, Object> parameters) {
		return dao.selectCountByWhere(parameters);
	}

	public boolean insert(SkUserJinbi obj) {
		super.beforeInsert(obj);
		obj.setId(baseKeyService.getKey("sk_user_jinbi"));
		return dao.insert(obj);
	}

	public boolean updateByMap(Map<String, Object> params) {
		return dao.updateByMap(params);
	}

	/**
	 * 签到,获取10、15、20金币
	 * 
	 * @param obj
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void qiandao() {
		SKUser user = sKUserService.getUser();
		List<SkUserJinbi> list = getTodayQiandao();
		if (CollectionUtils.isNotEmpty(list)) {
			BusinessExceptionUtil.threwException("今日已签到，请明日再来!");
		}
		int jinbi = getQiandaoJl();
		SkUserJinbi obj = initUserJinbi(user.getId(), 1, jinbi);
		addJbls(obj);
	}

	/**
	 * 金币补偿，管理员手工补偿金币
	 * 
	 * @param obj
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void buchang(long userid, int jinbi) {
		if (jinbi > 1000) {
			BusinessExceptionUtil.threwException("补偿不能大于1000!");
		}
		SKUser user = sKUserService.selectOne(userid);
		SkUserJinbi obj = initUserJinbi(user.getId(), 10, jinbi);
		addJbls(obj);
	}

	/**
	 * 浏览任务,金币50
	 * 
	 * @param obj
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void liulan(long userid) {
		SKUser user = sKUserService.selectOne(userid);
		SkUserJinbi obj = initUserJinbi(user.getId(), 11, 50);
		addJbls(obj);
	}

	/**
	 * 返款得积分,获取和价格等额的金币
	 * 
	 * @param obj
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void fankuan(Long userid, Integer jinbi) {
		SkUserJinbi obj = initUserJinbi(userid, 2, jinbi);
		addJbls(obj);
	}

	/**
	 * 注册账号 +100（一次性活动）
	 * 
	 * @param userId
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void addZcjl(Long userId) {
		SkUserJinbi obj = initUserJinbi(userId, 21, 100);
		addJbls(obj);
	}

	/**
	 * 邀请粉丝注册 +300
	 * 
	 * @param userId
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void addYqjl(Long userId) {
		SkUserJinbi obj = initUserJinbi(userId, 3, 300);
		addJbls(obj);
	}

	/**
	 * 单日申请10次 +200
	 * 
	 * @param userId
	 */
	// @Transactional(rollbackFor = Exception.class, propagation =
	// Propagation.REQUIRED)
	// public void addDrsq(Long userId) {
	// // typeId: 6:单日申请10次赠送200
	// addJbls(userId, 200L, 6L, 1L);
	// }

	/**
	 * 金币抽奖 每次扣除50金币
	 * 
	 * @param userId
	 */
	private SkUserJinbi addJbcj(Long userId, String remark) {
		SkUserJinbi obj = initUserJinbi(userId, 4, 50);
		obj.setRemark(remark);
		addJbls(obj);
		return obj;
	}

	/**
	 * 抽到金币
	 * 
	 * @param userId
	 */
	private SkUserJinbi addJbcj(Long userId, int jinbi) {
		SkUserJinbi obj = initUserJinbi(userId, 5, jinbi);
		addJbls(obj);
		return obj;
	}

	/**
	 * 金币兑换必中机会
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void dhbz(Long userId, Integer jinbi, Long busiid) {
		SKUserYue skUserYue = sKUserYueService.selectOne(userId);
		if (skUserYue == null || skUserYue.getJinbi() < jinbi) {
			BusinessExceptionUtil.threwException("金币余额不足!");
		}
		// 金币兑换必中机会
		addJbbz(userId, jinbi, busiid);
	}

	/**
	 * 金币兑换必中机会
	 * 
	 * @param userId
	 */
	private SkUserJinbi addJbbz(Long userId, Integer jinbi, Long busiid) {
		SkUserJinbi obj = initUserJinbi(userId, 8, jinbi);
		obj.setBusiid(busiid);
		addJbls(obj);
		return obj;
	}

	/**
	 * 组装金币单对象
	 * 
	 * @param userId
	 * @param type
	 * @param jinbi
	 * @return
	 */
	private SkUserJinbi initUserJinbi(Long userId, int typeid, int jinbi) {
		SkUserJinbi obj = new SkUserJinbi();
		obj.setJinbi(jinbi);
		obj.setUserid(userId);
		obj.setTypeid(typeid);
		// 收入金币类型
		// 1:签到,2是根据完成的申请,返回金币,3:邀请粉丝注册,5:抽奖抽到金币,6是单日申请10次,10:金币补偿,11:浏览任务
		// ,21:注册账号
		if (NumberUtils.equealEvenOne(typeid, 1, 2, 3, 5, 6, 10, 11, 21)) {
			obj.setInorout(1);
			// 支出金币类型 4:金币抽奖,8是兑换必中机会,12：礼品兑换
		} else if (NumberUtils.equealEvenOne(typeid, 4, 8, 12)) {
			obj.setInorout(-1);
		} else {
			BusinessExceptionUtil.threwException("无效的金币类型");
		}
		obj.setStatus(1);
		return obj;
	}

	/**
	 * 添加金币流水
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	private SkUserJinbi addJbls(SkUserJinbi jinbi) {
		if (jinbi.getUserid() == null) {
			BusinessExceptionUtil.threwException("用户不能为空");
		}
		if (jinbi.getJinbi() < 0) {
			BusinessExceptionUtil.threwException("金币不能小于0");
		}
		if (jinbi.getTypeid() <= 0) {
			BusinessExceptionUtil.threwException("类型不能为空");
		}
		if (jinbi.getInorout() != 1 && jinbi.getInorout() != -1) {
			BusinessExceptionUtil.threwException("请选择进出");
		}
		jinbi.setStatus(1);
//		sKUserYueService.updateJinbi(jinbi.getUserid(), new Double(jinbi.getJinbi()) * jinbi.getInorout());
		insert(jinbi);
		return jinbi;
	}

	/**
	 * 获取当天签到金币
	 */
	public List<SkUserJinbi> getTodayQiandao() {
		SKUser user = sKUserService.getUser();
		Map<String, Object> parameters = MapUtils.genMap("typeid", "1", "userid", user.getId(), "startCreatedTime", DateUtils.formatDateStart(new Date()));
		return selectByWhere(parameters);
	}

	/**
	 * 获取签到奖励
	 */
	public int getQiandaoJl() {
		SKUser user = sKUserService.getUser();
		Date qiantian = DateUtils.getPastDay(new Date(), -2);
		// 前天到今天有两次，奖励20金币
		long cishu = countQiandao(user, qiantian);
		if (cishu == 2) {
			return 20;
		}
		// 昨天到今天有一次，奖励15金币
		Date zuotian = DateUtils.getPastDay(new Date(), -1);
		cishu = countQiandao(user, zuotian);
		if (cishu == 1) {
			return 15;
		}
		return 10;
	}

	/**
	 * 获取x天内的签到次数
	 */
	public long countQiandao(SKUser user, Date day) {
		Map<String, Object> parameters = MapUtils.genMap("typeid", "1", "userid", user.getId(), "startCreatedTime", DateUtils.formatDateStart(day));
		long count = selectCountByWhere(parameters);
		return count;
	}

	/**
	 * 试客金币列表
	 *
	 * @return
	 */
	public List<SkUserJinbi> selectByUser(SKUser user, Integer inorout, Integer status) {
		Map<String, Object> parameters = MapUtils.genMap("userid", user.getId(), "orderby", "created_time desc");
		if (inorout != null) {
			parameters.put("inorout", inorout);
		}
		if (status != null) {
			parameters.put("status", status);
		}
		return selectByWhere(parameters);
	}

	/**
	 * 根据type统计出所有金币额
	 * 
	 * @param typeid
	 * @return
	 */
	public Long sumByType(Long typeid) {
		SKUser user = sKUserService.getUser();
		Map<String, Object> parameters = MapUtils.genMap("userid", user.getId());
		if (typeid != null) {
			parameters.put("typeid", typeid);
		}
		List<SkUserJinbi> list = selectByWhere(parameters);
		Long sum = 0L;
		for (SkUserJinbi jinbi : list) {
			sum += jinbi.getInorout() * jinbi.getJinbi();
		}
		return sum;
	}

	/**
	 * 统计今天剩余抽奖次数 (最多3次)
	 * 
	 * @return
	 */
	public Integer countTodayCj() {
		SKUser user = sKUserService.getUser();
		Map<String, Object> parameters = MapUtils.genMap("typeid", "4", "userid", user.getId(), "startCreatedTime", DateUtils.formatDateStart(new Date()));
		List<SkUserJinbi> list = selectByWhere(parameters);
		return 3 - list.size();
	}

	/**
	 * 金币抽奖
	 * 
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public Map<String, Object> choujiang() {
		SKUserYue skUserYue = sKUserYueService.selectByUser();
		if (skUserYue == null || skUserYue.getJinbi() < 50) {
			BusinessExceptionUtil.threwException("金币余额不足!");
		}
		Integer countTodayCj = countTodayCj();
		if (countTodayCj <= 0) {
			BusinessExceptionUtil.threwException("今日抽奖次数已用尽!");
		}

		SKUser user = sKUserService.getUser();

		// 获取抽奖的结果
		Integer result = getChoujiangResult();
		// 金币抽奖 -50
		SkUserJinbi skUserJinbi = addJbcj(user.getId(), result + "");

		// 剩余金币
		Double yueJinbi = skUserYue.getJinbi();
		// 抽奖结果： 现金
		if (result >= 0 && result <= 7) {
			Double yue = 0.0;
			switch (result) {
			case 0:// 0.01元现金
				yue = 0.01;
				break;
			case 1:// 0.02元现金
				yue = 0.02;
				break;
			case 2:// 0.05元现金
				yue = 0.05;
				break;
			case 3:// 0.1元现金
				yue = 0.1;
				break;
			case 4:// 2元现金
				yue = 2.0;
				break;
			case 5:// 5元现金
				yue = 5.0;
				break;
			case 6:// 10元现金
				yue = 10.0;
				break;
			case 7:// 30元现金
				yue = 30.0;
				break;
			default:
			}
			SKUserZhang skUserZhang = new SKUserZhang();
			skUserZhang.setUserid(user.getId());
			skUserZhang.setYue(yue);
			skUserZhang.setBusiid(skUserJinbi.getId());
			skUserZhang.setBusitypeid(7);
			skUserZhangService.add(skUserZhang);
		} else if (result == 9 || result == 10) {
			// 抽奖结果： 金币
			int jinbi = result == 9 ? 60 : 100;
			yueJinbi += jinbi;
			// 抽奖得金币
			addJbcj(user.getId(), jinbi);
		}
		Map<String, Object> map = new HashMap<>();
		map.put("result", result);
		map.put("jinbi", yueJinbi);
		map.put("count", countTodayCj - 1);
		return map;
	}

	/**
	 * 0://0.01元现金 概率: 10% [0,100) <br>
	 * 1://0.02元现金 概率: 10% [100,200) <br>
	 * 2://0.05元现金 概率: 10% [200,300) <br>
	 * 3://0.1元现金 概率: 10% [300,400) <br>
	 * 4://2元现金 概率: 2% [400,420) <br>
	 * 5://5元现金 概率: 0.5% [420,425) <br>
	 * 6://10元现金 概率: 0.2% [425,427)<br>
	 * 7://30元现金 概率: 0% <br>
	 * 8://50元现金 概率: 0% <br>
	 * 9://60金币 概率: 23.5% [428,666) <br>
	 * 10://100金币 概率: 10% [666,766) <br>
	 * 19://再接再厉 概率: 23.4% [766,1000)
	 * 
	 * @return
	 */
	public Integer getChoujiangResult() {
		Random random = new Random();
		int i = random.nextInt(1000);
		Integer result;
		if (i < 100) {
			result = 0;
		} else if (i < 200) {
			result = 1;
		} else if (i < 300) {
			result = 2;
		} else if (i < 400) {
			result = 3;
		} else if (i < 420) {
			result = 4;
		} else if (i < 425) {
			result = 5;
		} else if (i < 427) {
			result = 6;
		} else if (i < 666) {
			result = 9;
		} else if (i < 766) {
			result = 10;
		} else {
			result = 19;
		}
		return result;
	}
}
